package ge.modules.physics;

import ge.engine.Log;
import ge.engine.PositionableArea;
import ge.exceptions.FunctionNonSuported;
import ge.lowlevel.box2d.BoxGe;
import ge.lowlevel.box2d.FactoryBox2D;
import ge.lowlevel.js.box2d.FactoryBox2DJs;
import ge.modules.Module;
import ge.modules.drawables.ShapeModule;
import ge.modules.drawables.SquareModule;

public class PhysicSimpleBoxModule implements Module, PositionableArea
{
    private SquareModule squareBox;
    private BoxGe physbox;
    //This height and width are the middle part of the original. Because in Box2D the width is sized between
    //the center of the object to one of its sides.
    private double width, height;
    private double densidad;
    public PhysicSimpleBoxModule(PhysicsAttributes pAtt,double width, double height)
    {
    	densidad = pAtt.density;
    	this.width = width/2;
    	this.height =  height/2;
    	double scale =  FactoryBox2D.getActualWorld().getScale();
    	physbox = FactoryBox2D.get().newBox(FactoryBox2D.getActualWorld(),pAtt, this.width/scale, this.height/scale, 0, 0);
    	squareBox = new SquareModule(width,height);
    	squareBox.setVisible(false);
    	if(densidad == 0)
    		loadShapePoints();
    	
    }
    public PhysicSimpleBoxModule( PhysicsAttributes pAtt,double width, double height,double x, double y)
    {
    	densidad = pAtt.density;
    	this.width = width/2;
    	this.height =  height/2;
    	double scale =  FactoryBox2D.getActualWorld().getScale();
    	physbox = FactoryBox2D.get().newBox(FactoryBox2D.getActualWorld(), pAtt, this.width/scale, this.height/scale, (x+this.width)/scale, (y+this.height)/scale);
    	squareBox = new SquareModule(width,height);
    	squareBox.setVisible(false);
    	if(densidad == 0)
    		loadShapePoints();
    }
    public  SquareModule getShape()
    {
    	return squareBox;
    }
    private void loadShapePoints()
    {
    	  double scale = FactoryBox2D.getActualWorld().getScale();
    	  squareBox.setPos(physbox.getX()*scale-width, physbox.getY()*scale-height); //real position 
    }
	@Override
	public void update() 
	{
		if(densidad != 0)
			loadShapePoints();
		squareBox.update();
	}
	public BoxGe getPhysic()
	{
		return physbox;
	}
	/**
	 * 	Adds a impulse with (fx,fy) form the center of the figure 
	 * @param fx Force in x axis
	 * @param fy Force in y axis
	 */
	public void applyImpulse(double fx, double fy)
	{
		try {
			physbox.applyImpulse(fx, fy, physbox.getX(), physbox.getY());
		} catch (FunctionNonSuported e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 	Adds a impulse with (fx,fy) form the (x,y) point
	 * @param fx Force in x axis
	 * @param fy Force in y axis
	 * @param x X point where the force will be applied
	 * @param y Y point where the force will be applied
	 */
	public void applyImpulse(double fx, double fy, double x, double y)
	{
		double scale = FactoryBox2D.getActualWorld().getScale();
		try {
			physbox.applyImpulse(fx, fy, x/scale, y/scale);
		} catch (FunctionNonSuported e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public void draw() 
	{
		 
		if(squareBox.isVisible())
		{
			//shapebox.setPos(shapebox.getX()+width, shapebox.getY()+height); //ajusta el eje de coordenadas
			squareBox.draw();
			//shapebox.setPos(shapebox.getX()-width, shapebox.getY()-height); //ajusta el eje de coordenadas
		}
	}
	@Override
	public void setPos(double x, double y)
	{
		double scale = FactoryBox2D.getActualWorld().getScale();
		physbox.setPos((x+width)/scale, (y+height)/scale);
		//physbox.setPos((x)+width, (y)+height);
	}
	@Override
	public double getX() {
		
		return (physbox.getX()*FactoryBox2D.getActualWorld().getScale()-width);
		//return physbox.getX()-width;
	}
	@Override
	public double getY() {
		return physbox.getY()*FactoryBox2D.getActualWorld().getScale()-height;
		//return physbox.getY()-height;
	}
	@Override
	public double getWidth() {
		return width*2;
	 
	}
	
	public void setLinealVelocity(double x, double y)
	{
		physbox.setLinealVelocity(x, y);
	}
	
	public double getXLinealVelocity()
	{
		return physbox.getXLinealVelocity();
	}
	
	public double getYLinealVelocity()
	{
		return physbox.getYLinealVelocity();
	}
	@Override
	public double getHeight() {
		return height*2;
		
	}
	/**
	 *  @deprecated  Use only the constructor
	 * @param width
	 * @param height
	 */
	@Override
	public void setArea(double width, double height)
	{
	}
	@Override
	public void delete() 
	{
		Log.write("Try to delete this box -- PhysicSimpleBoxModule");
		
		 try {
			physbox.destroyBody(FactoryBox2D.getActualWorld());
		} catch (FunctionNonSuported e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}
